package old;

import old.interfaces.ZarzadcaPola;
import old.items.ElementPanelu;
import java.util.Vector;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;

public class Panel extends Pole
{   
    public static final int ODSWIEZ_ELEMENT  = 1;
    public static final int ODSWIEZ_WSZYSTKO = 2;
    private int coOdswiezyc = ODSWIEZ_WSZYSTKO;
    private int odswiezanyElement = -1;
    
    private Vector elementy = new Vector(10);
    
    public Font malaCzcionka = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_SMALL);
    public Font duzaCzcionka = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_MEDIUM);
    
    public int kolorTekstu = 0x0;
    public int kolorWybranegoTla = 0xeecc44;
    public int kolorWybranegoTekstu = 0x0099ff;
    
    private int pierwszyElement = 0;
    private int wybranyElement = 0;
    
    private int wysokoscElementow;
    private int szerokoscElementu;
    private int wysokoscSuwaka = 30;
    
    private double wspolczynnikPrzesuniecia;
    public Panel()
    {   
        wysokoscElementow = 0;
    }
    
    public void przygotuj(ZarzadcaPola z, int szerokosc, int wysokosc)
    {
        zarzadca = z;
        szerokoscElementu = szerokosc - 4 /* lewy i prawy margines */ - 9 /* szerokość suwaka */;
        if(elementy.size() == 1)
            wspolczynnikPrzesuniecia = 0;
        else
            wspolczynnikPrzesuniecia = (double)(wysokosc - wysokoscSuwaka) / (elementy.size() - 1);
    }
    
    public void dodaj(ElementPanelu element)
    {
        if(element == null)
            throw new NullPointerException("Podany element jest null.");
        element.ustawPanel(this, elementy.size());
        int w = element.minimalnaWysokosc();
        elementy.addElement(new Wrapper(element, w, wysokoscElementow));
        wysokoscElementow += w;
    }
    
    public void wstaw(ElementPanelu element, int indeks)
    {
        if(indeks < 0 || indeks >= elementy.size())
            throw new IllegalArgumentException("Nieprawidłowy indeks do wstawienia");
        if(element == null)
            throw new NullPointerException("Podany element jest null.");
        element.ustawPanel(this, elementy.size());
        int w = element.minimalnaWysokosc();
        elementy.insertElementAt(new Wrapper(element, w, wysokoscElementow), indeks);
        wysokoscElementow += w;
    }
    
    public void usun(ElementPanelu element)
    {
        if(element == null)
            throw new NullPointerException("Podany element jest null.");
        Wrapper w;
        for(int i = 0; i < elementy.size(); ++i)
        {
            w = (Wrapper)elementy.elementAt(i);
            if(w.element.equals(element))
            {
                wysokoscElementow -= w.wysokosc;
                elementy.removeElementAt(i);
                break;
            }
        }
    }
    
    public void usun(int indeksElementu)
    {
        if(indeksElementu < 0 || indeksElementu >= elementy.size())
            throw new IllegalArgumentException("indeksElementu < 0 lub indeksElementu > ilość elementów");
        wysokoscElementow -= ((Wrapper)elementy.elementAt(indeksElementu)).wysokosc;
        elementy.removeElementAt(indeksElementu);
    }
    
    public void odrysujElement(int ind)
    {
        odswiezanyElement = ind;
        coOdswiezyc |= ODSWIEZ_ELEMENT;
        zarzadca.odrysujPole();
    }

    public void aktualizujElement(int i)
    {
        Wrapper w = (Wrapper)elementy.elementAt(i);
        wysokoscElementow -= w.wysokosc;
        w.wysokosc = w.element.minimalnaWysokosc();
        wysokoscElementow += w.wysokosc;
        odrysujElement(i);
    }

    public void rysuj(Graphics g, int szerokosc, int wysokosc)
    {
        synchronized(this)
        {
            Wrapper w, p;
            int pozycja = 0;
            if((coOdswiezyc & ODSWIEZ_ELEMENT) == ODSWIEZ_ELEMENT)
            {
                w = (Wrapper)elementy.elementAt(odswiezanyElement);
                p = (Wrapper)elementy.elementAt(pierwszyElement);

                g.translate(2, w.pozycja - p.pozycja);
                
                if(odswiezanyElement == wybranyElement)
                {
                    g.setColor(kolorWybranegoTla);
                    g.fillRect(-2, 0, szerokoscElementu + 4, w.wysokosc);
                }
                g.setClip(0, 0, szerokoscElementu, w.wysokosc);
                w.element.rysuj(g, szerokoscElementu, w.wysokosc, odswiezanyElement == wybranyElement);
            }
            else if((coOdswiezyc & ODSWIEZ_WSZYSTKO) == ODSWIEZ_WSZYSTKO)
            {
                p = (Wrapper)elementy.elementAt(pierwszyElement);
                g.setColor(zarzadca.kolorTla());
                g.fillRect(0, 0, szerokosc, wysokosc);
                g.setColor(kolorTekstu);
                g.drawLine(szerokosc - 5, 0, szerokosc - 5, wysokosc - 1);
                g.fillRect(szerokosc - 8, (int)(wspolczynnikPrzesuniecia * wybranyElement), 7, wysokoscSuwaka);
                g.translate(2, 0);
                for(int i = pierwszyElement; i < elementy.size(); ++i)
                {
                    w = (Wrapper)elementy.elementAt(i);
                    pozycja = w.pozycja - p.pozycja;
                    
                    g.translate(0, pozycja);
                    
                    g.setClip(-2, 0, szerokosc, w.wysokosc);
                    if(i == wybranyElement)
                    {
                        g.setColor(kolorWybranegoTla);
                        g.fillRect(-2, 0, szerokoscElementu + 4, w.wysokosc);
                    }
                    g.setClip(0, 0, szerokoscElementu, w.wysokosc);
                    w.element.rysuj(g, szerokoscElementu, w.wysokosc, i == wybranyElement);
                    g.translate(0, -pozycja);
                }
            }
        }
    }

    public void obslugaKlawiszy(int kod)
    {
        int iloscElementow = elementy.size();
        boolean odmaluj = false;
        
        if(iloscElementow == 0)
            return;
        
        Wrapper p, w = (Wrapper)elementy.elementAt(wybranyElement);
        switch(kod)
        {
            case -1:    // UP
                if(w.element.akcja(kod) == false)
                {
                    if(wybranyElement > 0)
                    {
                        w.element.wyjscie();
                        wybranyElement--;
                        odmaluj = true;
                    }
                }
                break;
            case -2:    // DOWN
                if(w.element.akcja(kod) == false)
                {
                    if(wybranyElement < iloscElementow - 1)
                    {
                        w.element.wyjscie();
                        wybranyElement++;
                        odmaluj = true;
                    }
                }
                break;
            case -3:    // LEFT
            case -4:    // RIGHT
                w.element.akcja(kod);
                break;
            default:
                w.element.klawisz(kod);
                break;
        }
        if(odmaluj)
        {
            w = (Wrapper)elementy.elementAt(wybranyElement);
            p = (Wrapper)elementy.elementAt(pierwszyElement);
            w.element.wejscie();
            
            while(w.pozycja + w.wysokosc - p.pozycja > zarzadca.wysokoscPola())
                p = (Wrapper)elementy.elementAt(++pierwszyElement);
            if(w.pozycja - p.pozycja < 0)
                pierwszyElement = wybranyElement;
            coOdswiezyc = ODSWIEZ_WSZYSTKO;
            zarzadca.odrysujPole();
        }
    }
    
    public void wywolajZdarzenie(int kod)
    {
        if(odbiorca != null)
            odbiorca.zdarzeniePola(this, kod);
    }
    
    private class Wrapper
    {
        public ElementPanelu element;
        public int wysokosc;
        public int pozycja;
        public Wrapper(ElementPanelu e, int w, int p)
        {
            element = e;
            wysokosc = w;
            pozycja = p;
        }
    }
}
